`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2021/03/30 08:51:08
// Design Name: adi
// Module Name: axi_master
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module axi_master#(
    parameter   axi_data_width          =   512         
    )
(
    input   wire                sys_clk         ,
    input   wire                sys_rst         ,
    input   wire                start_axi       ,//start axi: pulse.
    input   wire                read_or_write   ,//0:read 1:writer
    
    input   wire    [31:0]      address         ,
    input   wire    [7:0]       burst_length    ,
    input   wire    [2:0]       burst_size      ,
    input   wire    [1:0]       increment_burst ,//01 = incrementing addresses, 00 = fixed addresses
    
    output  wire                busy_wr         ,//1:busy
    output  wire                error_wr        ,//1:error
    output  wire                done_wr         ,//1:complete
    
    output  wire                busy_rd         ,//1:busy
    output  wire                done_rd         ,
    output  wire                error_rd        ,
//---------------------data interfacec-------------------
//  data input
    input   wire    [axi_data_width-1:0]        din             ,//
    input   wire                din_valid       ,//
    output  wire                din_ready       ,//
//  data output
    output  wire    [axi_data_width-1:0]        dout            ,//
    output  wire                dout_valid      ,//
    input   wire                dout_ready      ,//
//---------------------axi interfacec-------------------
//  input   wire                m_axi_aclk      ,               
//  input   wire                m_axi_reset     ,
//  AXI4 Read Address Channel   
    input   wire                m_axi_arready   ,
    output  wire                m_axi_arvalid   ,
    output  wire    [31:0]      m_axi_araddr    ,           
    output  wire    [3:0]       m_axi_arid      ,           
    output  wire    [7:0]       m_axi_arlen     ,           
    output  wire    [2:0]       m_axi_arsize    ,           
    output  wire    [1:0]       m_axi_arburst   ,           
    output  wire                m_axi_arlock    ,        
    output  wire    [3:0]       m_axi_arcache   ,           
    output  wire    [2:0]       m_axi_arprot    ,           
    output  wire    [3:0]       m_axi_arqos     ,           
    output  wire    [3:0]       m_axi_arregion  ,           
//  outAXI4 Read Data Channel
    output  wire                m_axi_rready    ,          
    input   wire                m_axi_rvalid    ,       
    input   wire    [axi_data_width-1:0]        m_axi_rdata     ,       
    input   wire    [1:0]       m_axi_rresp     ,       
    input   wire    [3:0]       m_axi_rid       ,       
    input   wire                m_axi_rlast     ,           
//  AXI4 Write Address Channel
    input   wire                m_axi_awready   ,           
    output  wire                m_axi_awvalid   ,        
    output  wire    [31:0]      m_axi_awaddr    ,       
    output  wire    [3:0]       m_axi_awid      ,       
    output  wire    [7:0]       m_axi_awlen     ,       
    output  wire    [2:0]       m_axi_awsize    ,       
    output  wire    [1:0]       m_axi_awburst   ,       
    output  wire                m_axi_awlock    ,       
    output  wire    [3:0]       m_axi_awcache   ,       
    output  wire    [2:0]       m_axi_awprot    ,       
    output  wire    [3:0]       m_axi_awqos     ,       
    output  wire    [3:0]       m_axi_awregion  ,       
//  AXI4 Write Data Channel
    input   wire                m_axi_wready    ,           
    output  wire                m_axi_wvalid    ,        
    output  wire    [3:0]       m_axi_wid       ,       
    output  wire    [axi_data_width-1:0]        m_axi_wdata     ,        
    output  wire    [axi_data_width/8-1:0]      m_axi_wstrb     ,        
    output  wire                m_axi_wlast     ,        
//  AXI4 Write Response Channel
    output  wire                m_axi_bready    ,           
    input   wire                m_axi_bvalid    ,        
    input   wire    [1:0]       m_axi_bresp     ,        
    input   wire    [3:0]       m_axi_bid             
    );
    wire                    m_axi_aclk;
    wire                    m_axi_reset;
    assign  m_axi_aclk = sys_clk;
    assign  m_axi_reset = sys_rst;
    
    reg     [31:0]          wr_address              ;
    reg     [7:0]           wr_burst_length         ;
    reg     [6:0]           wr_burst_size           ;
    reg     [1:0]           wr_increment_burst      ;

    reg     [31:0]          rd_address              ;
    reg     [7:0]           rd_burst_length         ;
    reg     [6:0]           rd_burst_size           ;
    reg     [1:0]           rd_increment_burst      ;

    reg                     start_write;
    reg                     start_read;
            
    always @(posedge sys_clk)
        if(sys_rst)
            start_write <= 1'd0;
        else if(start_axi & read_or_write)
            start_write <= 1'd1;
        else
            start_write <= 1'd0;
        
    always @(posedge sys_clk)
        if(sys_rst)
            start_read <= 1'd0;
        else if(start_axi & (!read_or_write))
            start_read <= 1'd1;
        else
            start_read <= 1'd0; 
            
    axi_master_writer  #(
        .axi_data_width         (axi_data_width                 )
    )axi_master_writer_u0(
        .m_axi_aclk         (m_axi_aclk         ),
        .m_axi_reset        (m_axi_reset        ),
        .start_write        (start_write        ),
        .address            (address            ),
        .burst_length       (burst_length       ),    
        .burst_size         (burst_size         ),
        .increment_burst    (increment_burst    ),
        .done               (done_wr            ),
        .error              (error_wr           ),
        .busy               (busy_wr            ),
        .din                (din                ),
        .din_valid          (din_valid          ),
        .din_ready          (din_ready          ),
        .m_axi_awready      (m_axi_awready      ),
        .m_axi_awvalid      (m_axi_awvalid      ),
        .m_axi_awaddr       (m_axi_awaddr       ),
        .m_axi_awid         (m_axi_awid         ),
        .m_axi_awlen        (m_axi_awlen        ),
        .m_axi_awsize       (m_axi_awsize       ),
        .m_axi_awburst      (m_axi_awburst      ),
        .m_axi_awlock       (m_axi_awlock       ),
        .m_axi_awcache      (m_axi_awcache      ),
        .m_axi_awprot       (m_axi_awprot       ),
        .m_axi_awqos        (m_axi_awqos        ),
        .m_axi_awregion     (m_axi_awregion     ), 
        .m_axi_wready       (m_axi_wready       ),
        .m_axi_wvalid       (m_axi_wvalid       ),
        .m_axi_wid          (m_axi_wid          ),
        .m_axi_wdata        (m_axi_wdata        ),
        .m_axi_wstrb        (m_axi_wstrb        ),
        .m_axi_wlast        (m_axi_wlast        ), 
        .m_axi_bready       (m_axi_bready       ),
        .m_axi_bvalid       (m_axi_bvalid       ),
        .m_axi_bresp        (m_axi_bresp        ),
        .m_axi_bid          (m_axi_bid          )
    );
    axi_master_read  #(
        .axi_data_width         (axi_data_width                 )
    )axi_master_read_u0(
        .m_axi_aclk         (m_axi_aclk         ),
        .m_axi_reset        (m_axi_reset        ),
        .start_read         (start_read         ),
        .address            (address            ),
        .burst_length       (burst_length       ),
        .burst_size         (burst_size         ),
        .increment_burst    (increment_burst    ),
        .done               (done_rd            ),
        .error              (error_rd           ),
        .busy               (busy_rd            ),
        .dout               (dout               ),
        .dout_valid         (dout_valid         ),
        .dout_ready         (dout_ready         ),
        .m_axi_arready      (m_axi_arready      ),
        .m_axi_arvalid      (m_axi_arvalid      ),
        .m_axi_araddr       (m_axi_araddr       ),
        .m_axi_arid         (m_axi_arid         ),
        .m_axi_arlen        (m_axi_arlen        ),
        .m_axi_arsize       (m_axi_arsize       ),
        .m_axi_arburst      (m_axi_arburst      ),
        .m_axi_arlock       (m_axi_arlock       ),
        .m_axi_arcache      (m_axi_arcache      ),
        .m_axi_arprot       (m_axi_arprot       ),
        .m_axi_arqos        (m_axi_arqos        ),
        .m_axi_arregion     (m_axi_arregion     ),
        .m_axi_rready       (m_axi_rready       ),
        .m_axi_rvalid       (m_axi_rvalid       ),
        .m_axi_rdata        (m_axi_rdata        ),
        .m_axi_rresp        (m_axi_rresp        ),
        .m_axi_rid          (m_axi_rid          ),
        .m_axi_rlast        (m_axi_rlast        )
    );
    
    
endmodule
